home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / larn.lha / vms.c < prev    next >
C/C++ Source or Header  |  1995-11-19  |  7KB  |  234 lines

  1. #ifdef VMS
  2. #include "header.h"
  3.  
  4. #include <file.h>
  5. #include <stat.h>
  6. #include <stdio.h>
  7. #include <stsdef.h>
  8. #include <ssdef.h>
  9. #include <descrip.h>
  10. #include <iodef.h>
  11. #include <ttdef.h>
  12. #include <tt2def.h>
  13.  
  14. /*
  15.  * Read until end of file or until buffer is full.
  16.  * don't let the vms read (which stops once per record)
  17.  * fool the program.
  18.  */
  19. vread(fd, buf, size)
  20. int fd;
  21. char    *buf;
  22. int size;
  23. {
  24.     int csize;      /* cumulative size  */
  25.     int isize;      /* incremental size */
  26.  
  27.     csize = 0;
  28.     do {
  29.         isize = read(fd, buf, size);
  30.         if (isize > 0) {
  31.             csize += isize;
  32.             buf   += isize;
  33.             size  -= isize;
  34.         }
  35.     } while (isize > 0);
  36.     return (csize);
  37. }
  38.  
  39. #else VMS
  40.  
  41. #ifndef vread       /* if not done as a macro in header.h */
  42. vread(fd, buf, size)
  43. int fd;
  44. char    *buf;
  45. int size;
  46. {
  47.     return (read(fd, buf, size));
  48. }
  49. #endif vread
  50. #endif VMS
  51.  
  52. #ifdef VMS
  53. /*
  54.  * Run a command in a subjob.  Used for mailing the winners congratulations,
  55.  * tax bills, etc.  Used for the shell escape command (!).  Conditionalized
  56.  * for VMS wherever used (un*x has the right primitives).
  57.  */
  58. long
  59. oneliner(cstr)
  60. char    *cstr;
  61. {
  62.     struct  dsc$descriptor  cdsc;
  63.     register long       sts;
  64.     register long       pstat;
  65.  
  66.     cdsc.dsc$a_pointer = cstr;
  67.     cdsc.dsc$w_length  = strlen(cstr);
  68.     cdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  69.     cdsc.dsc$b_class   = DSC$K_CLASS_S;
  70.     sts = LIB$SPAWN(&cdsc, 0, 0, 0, 0, 0, &pstat, 0, 0, 0, 0, 0);
  71.     if (sts != SS$_NORMAL)
  72.         return (sts);
  73.     else
  74.         return (pstat);
  75. }
  76.  
  77. /*
  78.   Data to convert the escape codes produced by VT style keypad keys to things
  79.   that LARN will understand.
  80. */
  81. #define MAX_KP_CONV 19
  82. struct 
  83.     {
  84.     char *inp_str;
  85.     char *out_str;
  86.     } keypad_conv[MAX_KP_CONV] = { { "\x1BOp", "i" },      /* KP0 */
  87.                                    { "\x1BOq", "b" },      /* KP1 */
  88.                                    { "\x1BOr", "j" },      /* KP2 */
  89.                                    { "\x1BOs", "n" },      /* KP3 */
  90.                                    { "\x1BOt", "h" },      /* KP4 */
  91.                                    { "\x1BOu", "." },      /* KP5 */
  92.                                    { "\x1BOv", "l" },      /* KP6 */
  93.                                    { "\x1BOw", "y" },      /* KP7 */
  94.                                    { "\x1BOx", "k" },      /* KP8 */
  95.                                    { "\x1BOy", "u" },      /* KP9 */
  96.                    { "\x1BOn", "." },      /* KP. */
  97.                    { "\x1BOl", "," },      /* KP, */
  98.                    { "\x1B[A", "K" },      /* uparrow */
  99.                    { "\x1B[B", "J" },      /* downarrow*/
  100.                    { "\x1B[C", "L" },      /* right arrow */
  101.                    { "\x1B[D", "H" },      /* left arrow */
  102.                    { "\x1BOP", "m" },      /* PF1 */
  103.                    { "\x1BOS", "@" },      /* PF4 */
  104.                                    { "\x1B[23~", "\x1B" }  /* (ESC) */
  105.                                  };
  106.  
  107. /*
  108.   VMS-specific terminal character read.  Gets a character from the terminal,
  109.   translating keypad as necessary.  Assumes VT-class terminals.
  110. */
  111. vms_ttgetch()
  112.     {
  113.  
  114. #define BUFFLEN 10
  115.  
  116.     char           *i;
  117.     int            j;
  118.     register int   incount;
  119.     static char    buffer[BUFFLEN];
  120.     static char    *bufptr = buffer;
  121.     static char    *bufend = buffer;
  122.  
  123.     lflush();       /* be sure output buffer is flushed */
  124.  
  125.     /* Read the first char from the user
  126.     */
  127.     if (bufptr >= bufend) 
  128.         {
  129.         bufptr = bufend = buffer;
  130.         incount = vmsread(buffer, BUFFLEN, 0);
  131.         while ( incount <= 0 )
  132.             incount = vmsread(buffer, 1, 2);
  133.         bufend = &buffer[incount];
  134.         }
  135.  
  136.     /* If the first char was an ESCAPE, get the characters from an
  137.        escape sequence (eg pressing a key that generates such a
  138.        sequence).  If it was a plain old escape, the vmsread() call
  139.        will return TIMEOUT.
  140.     */
  141.     if (*bufptr == '\x1B' )
  142.         {
  143.         incount = vmsread( bufend, (BUFFLEN - 1), 0 );
  144.         if (incount >= 0)
  145.         bufend += incount ;
  146.     }
  147.  
  148.     /* Make sure the buffer is zero-terminated, since vmsread() 
  149.        doesn't zero-terminate the characters read.
  150.     */
  151.     *bufend = '\0' ;
  152.  
  153.     /* run through the keypad conversion table to convert keypad
  154.        keys (escape sequences) and other supported escape sequences
  155.        to Larn command characters.
  156.     */
  157.     for ( j = 0; j < MAX_KP_CONV ; j++ )
  158.         if (strcmp( &buffer, keypad_conv[j].inp_str ) == 0 )
  159.             {
  160.         strcpy( &buffer, keypad_conv[j].out_str );
  161.         bufend = &buffer[strlen(&buffer)];
  162.         break;
  163.         }
  164.  
  165.     /* If after running through the table the first character is still
  166.        ESCAPE, then we probably didn't get a match.  Force unsupported
  167.        keys that generate escape sequences to just return an ESCAPE.
  168.        Effectively prevents key translations that generate escape
  169.        sequences.
  170.     */
  171.     if (*bufptr == '\x1B' )
  172.         {
  173.     bufend = &buffer[1] ;
  174.     }
  175.     *bufend = '\0' ;
  176.  
  177.     if (*bufptr == '\r')
  178.         *bufptr = '\n';
  179.  
  180.     return (*bufptr++ & 0xFF);
  181.     }
  182.  
  183. typedef struct 
  184.     {
  185.     short int    status;
  186.     short int    term_offset;
  187.     short int    terminator;
  188.     short int    term_size;
  189.     } IOSTAB;
  190.  
  191. int vmsread(buffer, size, timeout)
  192. char       *buffer;
  193. int        size;
  194. int        timeout;
  195.     {
  196.  
  197. #define TIMEOUT (-2)
  198. #define ERROR   (-1)
  199.  
  200.     extern int        iochan;
  201.  
  202.     register int      status;
  203.     IOSTAB            iostab;
  204.     static long       termset[2] = { 0, 0 };      /* No terminator    */
  205.  
  206.     status = SYS$QIOW( 
  207.             0,               /* Event flag             */
  208.             iochan,          /* Input channel        */
  209.             IO$_READLBLK | IO$M_NOFILTR | IO$M_TIMED,
  210.                              /* Read, no echo, no translate    */
  211.             &iostab,         /* I/O status block        */
  212.             NULL,            /* AST block (none)        */
  213.             0,               /* AST parameter        */
  214.             buffer,          /* P1 - input buffer        */
  215.             size,            /* P2 - buffer length        */
  216.             timeout,         /* P3 - timeout            */
  217.             &termset,        /* P4 - terminator set        */
  218.             NULL,            /* P5 - ignored (prompt buffer)    */
  219.             0                /* P6 - ignored (prompt size)    */
  220.             );
  221.     if (status == SS$_TIMEOUT)
  222.         return (TIMEOUT);
  223.     else if (status != SS$_NORMAL)
  224.         return (ERROR);
  225.     else 
  226.         {
  227.         if ((status = iostab.term_offset + iostab.term_size) > 0)
  228.             return (status);
  229.         return (TIMEOUT);
  230.         }
  231.     }
  232.  
  233. #endif VMS
  234.